﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Script.Serialization;

namespace Derrick.Web
{
    public partial class TwitterFeedControl2 : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //getTwitterStatus();
            getTweets();
        }

        protected void getTweetsBroken()
        {

            //string oauth_consumer_key = "MeRJZn4Tx3S7BTEf5ToSw";
            string oauth_consumer_key = ConfigurationManager.AppSettings["TwitterOAuthConsumerKey"];
            string consumerSecret = ConfigurationManager.AppSettings["TwitterConsumerSecret"];
            string oauth_signature_method = ConfigurationManager.AppSettings["TwitterOAuthSignatureMethod"];
            string oauth_token = ConfigurationManager.AppSettings["TwitterOAuthToken"];
            string oauth_version = ConfigurationManager.AppSettings["TwitterOAuthVersion"];
            string oauth_token_secret = ConfigurationManager.AppSettings["TwitterOAuthTokenSecret"];

            OAuthBase oAuth = new OAuthBase();

            // string oauth_nonce = Convert.ToBase64String(
            //     new ASCIIEncoding().GetBytes(
            //         DateTime.Now.Ticks.ToString()));

            string oauth_nonce = oAuth.GenerateNonce();

            //string oauth_signature_method = "HMAC-SHA1";
            //string oauth_token =
            //    "1264407572-7kDxIvgULA3tS0gPga1t9uXXeJOP6hD0c98VFjG";

            // TimeSpan ts = DateTime.UtcNow -
            //     new DateTime(1970, 1, 1, 0, 0, 0, 0);

            //string oauth_timestamp =
            //    Convert.ToInt64(ts.TotalSeconds).ToString();

            string oauth_timestamp = oAuth.GenerateTimeStamp();

            //string oauth_version = "1.0";

            //GS - When building the signature string the params
            //must be in alphabetical order. I can't be bothered
            //with that, get SortedDictionary to do it's thing
            SortedDictionary<string, string> sd =
                new SortedDictionary<string, string>();

            sd.Add("count", "2");
            sd.Add("oauth_consumer_key", oauth_consumer_key);
            sd.Add("oauth_nonce", oauth_nonce);
            sd.Add("oauth_signature_method", oauth_signature_method);
            sd.Add("oauth_timestamp", oauth_timestamp);
            sd.Add("oauth_token", oauth_token);
            sd.Add("oauth_version", oauth_version);
            //sd.Add("status", status);
            sd.Add("screen_name", Uri.EscapeDataString("metrolinx"));

            //GS - Build the signature string
            string baseString = String.Empty;
            //baseString += "POST" + "&";
            baseString += "GET" + "&";
            //https://api.twitter.com/1/statuses/user_timeline.json?screen_name=metrolinx
            baseString += Uri.EscapeDataString(
                //"http://api.twitter.com/1/statuses/update.json")
                // "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=metrolinx")
                //ConfigurationManager.AppSettings["TwitterRestAPI"])
               "https://api.twitter.com/1.1/statuses/user_timeline.json")
                + "&";

            foreach (KeyValuePair<string, string> entry in sd)
            {
                baseString += Uri.EscapeDataString(entry.Key +
                    "=" + entry.Value + "&");
            }

            //GS - Remove the trailing ambersand char, remember 
            //it's been urlEncoded so you have to remove the 
            //last 3 chars - %26
            baseString =
                baseString.Substring(0, baseString.Length - 3);

            baseString = Uri.EscapeDataString(baseString);

            //GS - Build the signing key
            //string consumerSecret =
            //    "jNaFedHHbSkuWOW1e1cVUgK4V9VblB13fZttfGlH30";

            //string oauth_token_secret =
            //    "80GMSUebVQOtyVQkVwYxqTh2I6lvwGmlRiERwJt8d1I";

            string signingKey =
                Uri.EscapeDataString(consumerSecret) + "&" +
                Uri.EscapeDataString(oauth_token_secret);

            //GS - Sign the request
            HMACSHA1 hasher = new HMACSHA1(
                new ASCIIEncoding().GetBytes(signingKey));

            string signatureString = Convert.ToBase64String(
                hasher.ComputeHash(
                new ASCIIEncoding().GetBytes(baseString)));

            //string signatureString = oAuth.GenerateSignatureUsingHash(baseString, ;

            //string signatureString = null;
            //string authorizationUrlStr = @"https://api.twitter.com/oauth/authorize?oauth_token=" + oauth_token;
            //Uri authorizationUrl = new Uri(authorizationUrlStr);
            //string outputUrl = String.Empty;
            //string outputParams = String.Empty;
            //signatureString = oAuth.GenerateSignature(authorizationUrl, oauth_consumer_key, consumerSecret, oauth_token, oauth_token_secret, "POST", oauth_timestamp, oauth_nonce, out outputUrl, out outputParams);
            //signatureString = HttpUtility.UrlEncode(signatureString);

            //GS - Tell Twitter we don't do the 100 continue thing
            ServicePointManager.Expect100Continue = false;

            //GS - Instantiate a web request and populate the 
            //authorization header
            HttpWebRequest hwr =
                (HttpWebRequest)WebRequest.Create(ConfigurationManager.AppSettings["TwitterRestAPI"] + @"&count=" + ConfigurationManager.AppSettings["TweetsToReturn"]);

            string authorizationHeaderParams = String.Empty;
            authorizationHeaderParams += "OAuth ";
            authorizationHeaderParams += "oauth_nonce=" + "\"" +
                Uri.EscapeDataString(oauth_nonce) + "\",";

            authorizationHeaderParams +=
                "oauth_signature_method=" + "\"" +
                Uri.EscapeDataString(oauth_signature_method) +
                "\",";

            authorizationHeaderParams += "oauth_timestamp=" + "\"" +
                Uri.EscapeDataString(oauth_timestamp) + "\",";

            authorizationHeaderParams += "oauth_consumer_key="
                + "\"" + Uri.EscapeDataString(
                oauth_consumer_key) + "\",";

            authorizationHeaderParams += "oauth_token=" + "\"" +
                Uri.EscapeDataString(oauth_token) + "\",";

            authorizationHeaderParams += "oauth_signature=" + "\""
                + Uri.EscapeDataString(signatureString) + "\",";

            authorizationHeaderParams += "oauth_version=" + "\"" +
                Uri.EscapeDataString(oauth_version) + "\"";

            hwr.Headers.Add(
                "Authorization", authorizationHeaderParams);

            //GS - POST off the request
            hwr.Method = "GET";
            hwr.ContentType = "application/x-www-form-urlencoded";
            //Stream stream = hwr.GetRequestStream();
            //byte[] bodyBytes =
            //    new ASCIIEncoding().GetBytes(postBody);

            //stream.Write(bodyBytes, 0, bodyBytes.Length);
            //stream.Flush();
            //stream.Close();

            //GS - Allow us a reasonable timeout in case
            //Twitter's busy
            hwr.Timeout = 3 * 60 * 1000;

            try
            {
                HttpWebResponse rsp = hwr.GetResponse()
                    as HttpWebResponse;
                //GS - Do something with the return here...
                Stream responseStream = rsp.GetResponseStream();
                byte[] messageBytes = new byte[1024];
                StringBuilder singleTweet = new StringBuilder();
                // List<Tweet> allTweets = new List<Tweet>();
                int countOfCurlyBraces = 0;
                JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();

                while (responseStream.Read(messageBytes, 0, messageBytes.Length) > 0)
                {

                    //string message = Encoding.UTF8.GetString(messageBytes);
                    //allTweets.Append(message);
                    for (int i = 0; i < messageBytes.Length; i++)
                    {
                        if (messageBytes[i] == '[' || messageBytes[i] == ']')
                        {
                            continue;
                        }

                        singleTweet.Append(Encoding.UTF8.GetString(new byte[1] { messageBytes[i] }));

                        if (messageBytes[i] == '}')
                        {
                            countOfCurlyBraces++;
                            if (countOfCurlyBraces == 2)
                            {
                                Tweet singleTweetObject = new Tweet();
                                singleTweetObject.user = new TwitterUser();
                                //singleTweet = singleTweet.Replace(@"{{", @"{");
                                singleTweet = singleTweet.Replace(@"}}", @"}");
                                //singleTweet = singleTweet.Replace(@"{,{", @"{");
                                string singleTweetStr = singleTweet.ToString();
                                int startIndex = singleTweetStr.IndexOf(@"created_at") - 1;
                                singleTweetStr = @"{" + singleTweetStr.Substring(startIndex);
                                singleTweetObject = jsonSerializer.Deserialize<Tweet>(singleTweetStr);
                                //  allTweets.Add(singleTweetObject);
                                _restTweets.Text += @"<li><b>" + singleTweetObject.user.name + @"</b>: " + singleTweetObject.text + @"</li>";
                                singleTweet = new StringBuilder();
                                countOfCurlyBraces = 0;
                            }
                        }


                    }

                }



            }
            catch (WebException ex)
            {
                //GS - Do some clever error handling here...
                Response.Write(ex.ToString());
            }


        }

        private void getTweets()
        {
            // oauth application keys
            string oauth_token = ConfigurationManager.AppSettings["TwitterOAuthToken"];
            string oauth_token_secret = ConfigurationManager.AppSettings["TwitterOAuthTokenSecret"];
            string oauth_consumer_key = ConfigurationManager.AppSettings["TwitterOAuthConsumerKey"];
            string oauth_consumer_secret = ConfigurationManager.AppSettings["TwitterConsumerSecret"];

            // oauth implementation details
            string oauth_version = ConfigurationManager.AppSettings["TwitterOAuthVersion"];
            string oauth_signature_method = ConfigurationManager.AppSettings["TwitterOAuthSignatureMethod"];

            // unique request details
            string oauth_nonce = Convert.ToBase64String(
                new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
            TimeSpan timeSpan = DateTime.UtcNow
                - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            string oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();

            // message api details
            string status = "Updating status via REST API if this works";
            //var resource_url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
            string resource_url = ConfigurationManager.AppSettings["TwitterRestAPI1.1"];
            string screen_name = ConfigurationManager.AppSettings["TwitterScreenName"];
            string tweetsToReturn = ConfigurationManager.AppSettings["TweetsToReturn"];
            // create oauth signature
            string baseFormat = "count={0}&oauth_consumer_key={1}&oauth_nonce={2}&oauth_signature_method={3}" +
                            "&oauth_timestamp={4}&oauth_token={5}&oauth_version={6}&screen_name={7}";

            string baseString = string.Format(baseFormat,
                                        tweetsToReturn,
                                        oauth_consumer_key,
                                        oauth_nonce,
                                        oauth_signature_method,
                                        oauth_timestamp,
                                        oauth_token,
                                        oauth_version,
                                         Uri.EscapeDataString(screen_name)
                                        );

            baseString = string.Concat("GET&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString));

            string compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
                                    "&", Uri.EscapeDataString(oauth_token_secret));

            string oauth_signature;
            using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
            {
                oauth_signature = Convert.ToBase64String(
                    hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
            }

            // create the request header
            string headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
                               "oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
                               "oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
                               "oauth_version=\"{6}\"";

            string authHeader = string.Format(headerFormat,
                                    Uri.EscapeDataString(oauth_nonce),
                                    Uri.EscapeDataString(oauth_signature_method),
                                    Uri.EscapeDataString(oauth_timestamp),
                                    Uri.EscapeDataString(oauth_consumer_key),
                                    Uri.EscapeDataString(oauth_token),
                                    Uri.EscapeDataString(oauth_signature),
                                    Uri.EscapeDataString(oauth_version)
                            );


            // make the request

            ServicePointManager.Expect100Continue = false;

            string postBody = "screen_name=" + Uri.EscapeDataString(screen_name);//
            postBody += "&count=" + Uri.EscapeDataString(tweetsToReturn);
            resource_url += "?" + postBody;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url);
            request.Headers.Add("Authorization", authHeader);
            request.Method = "GET";
            request.ContentType = "application/x-www-form-urlencoded";


            try
            {
                WebResponse response = request.GetResponse();
                string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();

                responseData = responseData.Replace(@"[", String.Empty);
                responseData = responseData.Replace(@"]", String.Empty);
                string[] tokens = new string[1];
                tokens[0] = @"},{";
                string[] tweets = responseData.Split(tokens, StringSplitOptions.RemoveEmptyEntries);
                int numberOfTweets = tweets.Count();

                for (int i = 0; i < numberOfTweets; i++)
                {

                    string[] tokenSeparators = new string[1];
                    tokenSeparators[0] = "\",\"";
                    string[] keyValuePairs = tweets[i].Split(tokenSeparators, StringSplitOptions.RemoveEmptyEntries);
                    string screenName = String.Empty;
                    string tweetText = String.Empty;
                    for (int j = 0; j < keyValuePairs.Count(); j++)
                    {
                        if (keyValuePairs[j].Contains("\"screen_name\""))
                        {
                            if (String.IsNullOrEmpty(screenName))
                            {
                                screenName = keyValuePairs[j].Substring(keyValuePairs[j].IndexOf(@"screen_name") + 14);
                            }
                        }
                        else if (keyValuePairs[j].Contains("text\""))
                        {
                            if (String.IsNullOrEmpty(tweetText))
                            {
                                tweetText = keyValuePairs[j].Substring(7);
                            }
                        }
                        
                    }
                    _restTweets.Text += @"<li><b>" + screenName + @"</b>: " + tweetText + @"</li>";

                }


                //_restTweets.Text = @"<li>" + responseData + @"</li>";
            }
            catch (Exception ex)
            {
                Response.Write(ex.ToString());
            }
        }

        private void getTwitterStatus()
        {
            // oauth application keys
            var oauth_token = ConfigurationManager.AppSettings["TwitterOAuthToken"];
            var oauth_token_secret = ConfigurationManager.AppSettings["TwitterOAuthTokenSecret"];
            var oauth_consumer_key = ConfigurationManager.AppSettings["TwitterOAuthConsumerKey"];
            var oauth_consumer_secret = ConfigurationManager.AppSettings["TwitterConsumerSecret"];

            // oauth implementation details
            var oauth_version = ConfigurationManager.AppSettings["TwitterOAuthVersion"];
            var oauth_signature_method = ConfigurationManager.AppSettings["TwitterOAuthSignatureMethod"];

            // unique request details
            var oauth_nonce = Convert.ToBase64String(
                new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
            var timeSpan = DateTime.UtcNow
                - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();

            // message api details
            var status = "Updating status via REST API if this works";
            var resource_url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
            var screen_name = "updateme";
            // create oauth signature
            var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
                            "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&screen_name={6}";

            var baseString = string.Format(baseFormat,
                                        oauth_consumer_key,
                                        oauth_nonce,
                                        oauth_signature_method,
                                        oauth_timestamp,
                                        oauth_token,
                                        oauth_version,
                                         Uri.EscapeDataString(screen_name)
                                        );

            baseString = string.Concat("GET&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString));

            var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
                                    "&", Uri.EscapeDataString(oauth_token_secret));

            string oauth_signature;
            using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
            {
                oauth_signature = Convert.ToBase64String(
                    hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
            }

            // create the request header
            var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
                               "oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
                               "oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
                               "oauth_version=\"{6}\"";

            var authHeader = string.Format(headerFormat,
                                    Uri.EscapeDataString(oauth_nonce),
                                    Uri.EscapeDataString(oauth_signature_method),
                                    Uri.EscapeDataString(oauth_timestamp),
                                    Uri.EscapeDataString(oauth_consumer_key),
                                    Uri.EscapeDataString(oauth_token),
                                    Uri.EscapeDataString(oauth_signature),
                                    Uri.EscapeDataString(oauth_version)
                            );


            // make the request

            ServicePointManager.Expect100Continue = false;

            var postBody = "screen_name=" + Uri.EscapeDataString(screen_name);//
            resource_url += "?" + postBody;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url);
            request.Headers.Add("Authorization", authHeader);
            request.Method = "GET";
            request.ContentType = "application/x-www-form-urlencoded";

            try
            {
                WebResponse response = request.GetResponse();
                string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();

                _restTweets.Text = @"<li>" + responseData + @"</li>";
            }
            catch (Exception ex)
            {
                Response.Write(ex.ToString());
            }
        }

    }
}